import { Falsy } from './familiarize_strange';
// 类型别名中的泛型: 本质是一个函数
type Factory<T> = T | number | string;

// 类似 \v
function Factory(typeArg) {
  return [typeArg, number, string];
}

// 类型别名中的泛型大多 是 用来 工具类型封装;
// T: 联合类型
// in: 遍历联合类型中的类型定义
type stringify<T> = {
  [K in keyof T]: string;
};
// Clone
type Clone<T> = {
  [K in keyof T]: T[K];
};

// keyof 是什么 
// 类似 JS中的Object.keys 
const obj1 = {
  name2: "test",
  age: 18,
};
// 
Object.keys(obj1);
type ObjType = {
  name: string;
  age: number;
};
// keyof 获取 类型别名 ObjType 中的类型定义
type Obj = keyof ObjType;

// 声明两个变量 
const testObj: Obj = 'name';
const testObj2: Obj = 'age';

// in keyof 联合类型
// 复制工具类型 xxx ,
type Partial<T> = {
    [P in keyof T]? :T[P];
}
interface IFoo {
    prop1: string;
    prop2: number;
    prop3: boolean;
    prop4: () => void;// 函数(无返回值)
} 
// type PartialIFoo = Partial<IFoo>; // 等价于 \v;
interface PartialIFoo {
    prop1?: string;
    prop2?:number;
    prop3?: boolean;
    prop4?: ()=> void;
}

// 泛型约束与默认值
// 泛型 T == 联合类型interface; 简写;
// <泛型 = 布尔值>;

// 声明默认值
type Factory1<T = boolean> = T | number | string;
// 调用方便
const foo4: Factory1 = false;

// 伪代码 \v  return 泛型T 
// function Factory3(typeArg = boolean) {
//     return [typeArg,number,string]
// }

// 泛型约束 typeof == 类型测试
function add3(source: number,add: number) {
    if(typeof source !== 'number' || typeof add !== 'number') {
        // 如果 source 不等于 number 或者 add 不等于 number
        throw new Error("Invalid arguments!")
    }
}
// extends  A extends B;
type ResStatus<ResCode extends number> = ResCode extends 10000 | 10001 | 10002 ? 'success' : 'failure';

type Ress = ResStatus<10000>; // 'success' 符合 10000 | 10001 | 10002 类型 返回 success;
type Res2 = ResStatus<20000>; // 'failure' 符合number类型 返回 failure;

// type Res3 = ResStatus<'10000'>; // 不满足 上面三目运算 返回值; error

// 多泛型关联;
type Conditional<Type, Conditionm, TruthyResult,FalsyResult> = Type extends Condition ? TruthyResult : FalsyResult;

// "passed!"
type Result1 = Conditional<'linbudu', string, 'passed!', 'rejected!'>;

// "rejected!"
type Result2 = Conditional<'linbudu', boolean,'passed!', 'rejected!'>;

// SecondInput 继承 Input, ThirdInput 继承 SceondInput  均为 number 类型;
type ProcessInput<Input,SecondInput extends Input = Input,ThirdInput extends Input = SecondInput> = number;

// 对象类型中的泛型
interface IRes<TData = unknown> {
    code: number;
    error?: string;
    data: TData;
}


interface IUserProfileRes {
    name3: string;
    homepage: string;
    avatar: string;
}

function fetUserProfile(): Promise<IRes<IUserProfileRes>> {}
type StatusSucceed = boolean;
function handleOperation(): Promise<IRes<StatusSuccees>> {}

interface IPaginationRes<TIem = unknown> {
    data: TItem[];
    page: number;
    totalCount: number;
    hasNextPage: boolean;
}
// 异步类型的泛型嵌套;
function fetchUserProfileList(): Promise<IRes<IPaginationRes<IUserProfileRes>>>{}

// 函数中的泛型 any(为所欲为?)
function handle(input: any): any {};

// 可以写成所有类型? 
function handle2(input: string | number | {}): string | number | {} {}

const shouldBeString = handle("azyyzaz");
const shouldBeNumber = handle(599);
const shouldBeObject = handle({name: "azyyzaz"});

function handle3(input: string): string;
function handle4(input: number): number;
function handle5(input: {}): {};
function handle6(input: string | number | {}): string | number | {} { }






